package com.ychong.library.view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.os.Build
import android.text.TextPaint
import android.util.AttributeSet
import android.util.TypedValue
import android.view.MotionEvent
import android.view.View
import com.ychong.library.R
import com.ychong.library.utils.ResUtils

/**
 * 车牌号键盘
 */
class YCHPlateKeyBoardView : View {

    private var mRemoveIcon: Int
    private lateinit var removeBitmap: Bitmap
    private var mBoxHeight: Float
    private var mOtherBgColor: Int
    private var mClickBgColor: Int
    private var mNoClickTextColor: Int
    private var mNoClickBgColor: Int
    private var mCommonTextColor: Int
    private var mCommonTextSize: Float
    private var mCommonBgColor: Int
    private var mRadiusSize: Float

    private var boxWidth: Float = 0f
    private var paint: Paint? = null
    private var textPaint: TextPaint? = null
    private var provinceArr = arrayListOf(
        "京", "沪", "粤", "津", "冀", "晋", "蒙", "辽", "吉", "黑",
        "苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "桂",
        "琼", "渝", "川", "贵", "云", "藏", "陕", "甘", "青", "宁",
        "ABC", "新", "使", "领", "警", "学", "港", "澳", "-"
    )
    private var numberLetterArr = arrayOf(
        "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
        "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
        "A", "S", "D", "F", "G", "H", "J", "K", "L",
        "地区", "Z", "X", "C", "V", "B", "N", "M", "-"
    )
    private var mSpace: Float
    private var curType: Int = TYPE_PROVINCE

    private var clickIndex: Int = -1

    companion object {
        const val TYPE_PROVINCE = 0
        const val TYPE_NUMBER_LETTER = 1

        const val NUMBER = 10

        const val TYPE_TEXT_ABC = "ABC"
        const val TYPE_TEXT_DIQU = "地区"
        const val TYPE_TEXT_REMOVE = "-"
    }

    private var onKeyBoardListener: OnKeyBoardListener? = null
    fun setOnKeyBoardListener(onKeyBoardListener: OnKeyBoardListener) {
        this.onKeyBoardListener = onKeyBoardListener
    }

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attributeSet: AttributeSet?) : this(context, attributeSet, 0)

    @SuppressLint("Recycle")
    constructor(context: Context, attributeSet: AttributeSet?, defStyle: Int) : super(
        context,
        attributeSet,
        defStyle
    ) {
        val style = context.obtainStyledAttributes(
            attributeSet,
            R.styleable.YCHPlateKeyBoardView,
            0,
            defStyle
        )
        style.getDimensionPixelSize(
            R.styleable.YCHPlateKeyBoardView_pkbvHeight,
            TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50f, resources.displayMetrics)
                .toInt()
        )
        mBoxHeight = style.getDimensionPixelSize(
            R.styleable.YCHPlateKeyBoardView_pkbvHeight,
            TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50f, resources.displayMetrics)
                .toInt()
        ).toFloat()
        mSpace = style.getDimensionPixelSize(
            R.styleable.YCHPlateKeyBoardView_pkbvSpace,
            TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5f, resources.displayMetrics)
                .toInt()
        ).toFloat()
        mRadiusSize = style.getDimensionPixelSize(
            R.styleable.YCHPlateKeyBoardView_pkbvRadiusSize,
            TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5f, resources.displayMetrics)
                .toInt()
        ).toFloat()
        mCommonBgColor = style.getColor(
            R.styleable.YCHPlateKeyBoardView_pkbvCommonBgColor,
            ResUtils.getColor(context, R.color.color_white)
        )
        mCommonTextSize = style.getDimensionPixelSize(
            R.styleable.YCHPlateKeyBoardView_pkbvCommonTextSize,
            TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16f, resources.displayMetrics)
                .toInt()
        ).toFloat()
        mCommonTextColor = style.getColor(
            R.styleable.YCHPlateKeyBoardView_pkbvCommonTextColor,
            ResUtils.getColor(context, R.color.color_333333)
        )
        mNoClickBgColor = style.getColor(
            R.styleable.YCHPlateKeyBoardView_pkbvNoClickBgColor,
            ResUtils.getColor(context, R.color.color_E6E7EB)
        )
        mNoClickTextColor = style.getColor(
            R.styleable.YCHPlateKeyBoardView_pkbvNoClickTextColor,
            ResUtils.getColor(context, R.color.color_666666)
        )
        mClickBgColor = style.getColor(
            R.styleable.YCHPlateKeyBoardView_pkbvClickBgColor,
            ResUtils.getColor(context, R.color.color_0D71DF)
        )
        mOtherBgColor = style.getColor(
            R.styleable.YCHPlateKeyBoardView_pkbvOtherBgColor,
            ResUtils.getColor(context, R.color.color_B1B8C8)
        )
        mRemoveIcon = style.getInt(R.styleable.YCHPlateKeyBoardView_pkbvRemoveIcon,R.mipmap.ic_remove)
        init()
    }

    private fun init() {
        paint = Paint()
        paint!!.style = Paint.Style.FILL
        paint!!.isAntiAlias = true
        textPaint = TextPaint()
        textPaint!!.isAntiAlias = true
        textPaint!!.color = mCommonTextColor
        textPaint!!.textSize =mCommonTextSize

      removeBitmap = createBitmap(mRemoveIcon)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val width = MeasureSpec.getSize(widthMeasureSpec)
        val height = (4 * (2 * mSpace + mBoxHeight) + 2 * mSpace).toInt()
        setMeasuredDimension(width, height)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val x = event!!.x
        val y = event.y
        if (x <= mSpace && x >= width - mSpace && y <= 2 * mSpace && y >= height - 2 * mSpace) return true
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                when (curType) {
                    TYPE_PROVINCE -> {
                        if (!touchForProvince(x, y)) {
                            return false
                        }
                    }
                    TYPE_NUMBER_LETTER -> {
                        if (!touchForNumberLetter(x, y)) {
                            return false
                        }
                    }
                    else -> {
                        return false
                    }
                }
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                var text = ""
                if (curType == TYPE_PROVINCE) {
                    text = provinceArr[clickIndex]
                } else if (curType == TYPE_NUMBER_LETTER) {
                    text = numberLetterArr[clickIndex]
                }
                if (text == TYPE_TEXT_ABC) {
                    curType = TYPE_NUMBER_LETTER
                } else if (text == TYPE_TEXT_DIQU) {
                    curType = TYPE_PROVINCE
                }
                clickIndex = -1
                postInvalidateDelayed(100)
            }
        }
        return true
    }

    private fun touchForProvince(x: Float, y: Float): Boolean {
        val row: Int = (y / (mBoxHeight + mSpace * 2)).toInt()
        if (row == 3) {
            clickIndex = if (x <= mSpace + boxWidth * 1.5f
                && y >= (mSpace * 2 + mBoxHeight) * row && y <= (mSpace * 2 + mBoxHeight) * (row + 1)
            ) {
                row * NUMBER
            } else if (x <= width && x >= width - (mSpace * 2 + boxWidth * 1.5)
                && y >= (mSpace * 2 + mBoxHeight) * row && y <= (mSpace * 2 + mBoxHeight) * (row + 1)
            ) {
                provinceArr.size - 1
            } else {
                val cow: Int =
                    ((x - mSpace - boxWidth * 1.5) / (mSpace + boxWidth)).toInt()
                row * NUMBER + 1 + cow
            }
        } else if (row == 0 || row == 1 || row == 2) {
            val cow: Int = (x / (boxWidth + mSpace)).toInt()
            clickIndex = row * NUMBER + cow
        } else {
            return false
        }
        invalidate()
        return true
    }

    private fun touchForNumberLetter(x: Float, y: Float): Boolean {
        val row: Int = (y / (mBoxHeight + mSpace * 2)).toInt()
        if (row == 0 || row == 1) {
            val cow: Int = (x / (boxWidth + mSpace)).toInt()
            clickIndex = row * NUMBER + cow
        } else if (row == 2) {
            if (x > (mSpace + boxWidth / 2) && x < width - (mSpace + boxWidth / 2)) {
                val cow: Int =
                    ((x - mSpace - boxWidth / 2) / (mSpace + boxWidth)).toInt()
                clickIndex = row * NUMBER + cow
            } else {
                return false
            }
        } else if (row == 3) {
            clickIndex = if (x >= mSpace && x <= mSpace + (boxWidth * 1.5)
                && y >= (mSpace * 2 + mBoxHeight) * row && y <= (mSpace * 2 + mBoxHeight) * (row + 1)
            ) {
                (row - 1) * NUMBER + (NUMBER - 1)
            } else if (x >= width - (mSpace + boxWidth * 1.5) && x <= width - mSpace
                && y >= (mSpace * 2 + mBoxHeight) * row && y <= (mSpace * 2 + mBoxHeight) * (row + 1)
            ) {
                numberLetterArr.size - 1
            } else {
                val cow: Int =
                    ((x - mSpace - boxWidth * 1.5) / (mSpace + boxWidth)).toInt()
                (row - 1) * NUMBER + (NUMBER - 1) + 1 + cow
            }
        } else {
            return false
        }
        invalidate()
        return true
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        boxWidth = (width - (NUMBER + 1) * mSpace) / NUMBER
        if (curType == TYPE_PROVINCE) {
            drawProvince(canvas)
        } else if (curType == TYPE_NUMBER_LETTER) {
            drawNumberLetter(canvas)
        }
    }

    /**绘制省简称键盘*/
    private fun drawProvince(canvas: Canvas?) {
        var startX = 0f
        var startY = 0f
        var row = 0
        for (index in provinceArr.indices) {
            val text = provinceArr[index]
            if (index % NUMBER == 0) {
                startX = mSpace
                startY = row * mBoxHeight + (row + 1) * (mSpace * 2)
                row++
            }
            val left: Float = startX
            val top: Float = startY
            var right: Float = (startX + boxWidth)
            if (text == TYPE_TEXT_ABC || text == TYPE_TEXT_REMOVE) {
                right += (boxWidth + mSpace) * 0.5f
            }
            val bottom: Float = (startY + mBoxHeight)
            if (clickIndex == index) {
                paint!!.color = mClickBgColor
            } else {
                if (text == TYPE_TEXT_ABC || text == TYPE_TEXT_REMOVE) {
                    paint!!.color = mOtherBgColor
                } else {
                    paint!!.color = mCommonBgColor
                }
            }
            drawBox(canvas, left, top, right, bottom)
            if (text== TYPE_TEXT_REMOVE){
                drawRemove(canvas,left,top,right,bottom)
            }else{
                drawText(canvas, text, left, top, right, bottom)
            }
            startX += boxWidth + mSpace
            if (text == TYPE_TEXT_ABC || text == TYPE_TEXT_REMOVE) {
                startX += (boxWidth + mSpace) * 0.5f
            }
        }
        if (clickIndex != -1) {
            when (val text = provinceArr[clickIndex]) {
                TYPE_TEXT_REMOVE -> {
                    onKeyBoardListener?.remove()
                }
                TYPE_TEXT_ABC -> {

                }
                else -> {
                    onKeyBoardListener?.click(text)
                }
            }

        }

    }

    /**绘制数字字母键盘*/
    private fun drawNumberLetter(canvas: Canvas?) {
        var startX = 0f
        var startY = 0f
        for (index in numberLetterArr.indices) {
            val text = numberLetterArr[index]
            val row = if (index < 20) {
                ((index) / NUMBER)
            } else {
                (index - 20) / (NUMBER - 1) + 2
            }
            if (row == 0 || row == 1) {
                if (index % NUMBER == 0) {
                    startX = mSpace
                    startY = row * mBoxHeight + (row + 1) * (mSpace * 2)
                }
            } else if (row == 2) {
                if (((index) - 20) % (NUMBER - 1) == 0) {
                    startX = mSpace + boxWidth / 2
                    startY = row * mBoxHeight + (row + 1) * (mSpace * 2)
                }
            } else if (row == 3) {
                if ((index - 29) % (NUMBER - 1) == 0) {
                    startX = mSpace
                    startY = row * mBoxHeight + (row + 1) * (mSpace * 2)
                }
            }

            val left = startX
            val top = startY
            var right = startX + boxWidth
            if (text == TYPE_TEXT_DIQU || text == TYPE_TEXT_REMOVE) {
                right += (boxWidth + mSpace) * 0.5f
            }
            val bottom = startY + mBoxHeight
            if (text == "I" || text == "O") {
                paint!!.color = mNoClickBgColor
            } else {
                if (clickIndex == index) {
                    paint!!.color = mClickBgColor
                } else {
                    if (text == TYPE_TEXT_DIQU || text == TYPE_TEXT_REMOVE) {
                        paint!!.color = mOtherBgColor
                    } else {
                        paint!!.color = mCommonBgColor
                    }
                }
            }
            drawBox(canvas, left, top, right, bottom)
            if (text == TYPE_TEXT_REMOVE){
                drawRemove(canvas,left,top,right,bottom)
            }else{
                drawText(canvas, text, left, top, right, bottom)
            }

            startX += boxWidth + mSpace
            if (text == TYPE_TEXT_DIQU || text == TYPE_TEXT_REMOVE) {
                startX += (boxWidth + mSpace) * 0.5f
            }
        }
        if (clickIndex != -1) {
            when (val text = numberLetterArr[clickIndex]) {
                TYPE_TEXT_REMOVE -> {
                    onKeyBoardListener?.remove()
                }
                TYPE_TEXT_DIQU, "I", "O" -> {

                }
                else -> {
                    onKeyBoardListener?.click(text)
                }
            }

        }
    }

    /**绘制按键*/
    private fun drawBox(canvas: Canvas?, left: Float, top: Float, right: Float, bottom: Float) {
        if (Build.VERSION.SDK_INT >= 21) {
            canvas!!.drawRoundRect(left, top, right, bottom, 5f, 5f, paint!!)
        } else {
            val rectF = RectF(left, top, right, bottom)
            canvas!!.drawRoundRect(rectF, 5f, 5f, paint!!)
        }
    }

    /**绘制字体*/
    private fun drawText(
        canvas: Canvas?,
        text: String,
        left: Float,
        top: Float,
        right: Float,
        bottom: Float
    ) {
        val textWidth = textPaint!!.measureText(text)
        val pfm = textPaint!!.fontMetrics
        val textHeight = pfm.descent - pfm.ascent
        canvas!!.drawText(
            text,
            (left + right - textWidth) / 2,
            (top + bottom + textHeight) / 2,
            textPaint!!
        )
    }

    /**绘制移除按钮图片*/
    private fun drawRemove(canvas: Canvas?,left: Float,top: Float,right: Float,bottom: Float){
        val clearRect = Rect(
            (left+2*mSpace).toInt(),
            (top+2*mSpace).toInt(),
            (right-2*mSpace).toInt(),
            (bottom-2*mSpace).toInt()
        )
        canvas!!.drawBitmap(removeBitmap, null, clearRect, paint)
    }

    private fun createBitmap(resId: Int): Bitmap {
        return BitmapFactory.decodeResource(context.resources, resId)
    }

    interface OnKeyBoardListener {
        fun click(text: String)
        fun remove()
    }
}